﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace CRUD
{
    public class server
    {
        TcpListener serverLi = null;
        public static int port = 4545;
        public static List<Client> lst = new List<Client>();
        public bool state;
        public static IDS ids = null;
        public class Client
        {
            public Thread thr;
            public server srv;
            public NetworkStream networkStream;
            public Socket ThisSocket = null;
            string msg;
            public Client(Socket RecSoc,server curser)
            {
                ThisSocket = RecSoc;
                srv = curser;
                thr = new Thread(connect);
                networkStream = new NetworkStream(ThisSocket);
                thr.Start();
            }
            void send()
            {
                Console.WriteLine("Server respond:  "+msg);
                byte[] outStream = System.Text.Encoding.UTF8.GetBytes(msg);
                networkStream.Write(outStream, 0, outStream.Length);
                networkStream.Flush();
               // srv.Stop();
            }
            void action(string message)
            {
                //thr.Abort();
                string[] splited = message.Split(';','*');
                Console.WriteLine("recieved:  "+message);
                //   Console.WriteLine(msplited[2]essage);
               // string path = @"c:\temp\list.csv";
                string path = splited[1];
                ids = Factory.gi(path);
                MyList x = new MyList();
                //string[] strArray = message.Split('*', ' ');
                switch (splited[0])
                {
                    case "Create":
                        Person p = new Person();
                        p.id = Convert.ToInt32(splited[2]);
                        p.FName = splited[3];
                        p.LName = splited[4];
                        p.Age = Convert.ToInt32(splited[5]);
                        ids.Create(p);
                        break;
                    case "Read":
                        x.read(path);
                        msg = "";
                        foreach (Person pp in x)
                        {
                            msg += pp.SaveToSCV();
                            msg += "<";
                        }
                        if (x == null) 
                        {
                            msg = "null";
                        }
                        send();
                        break;
                    case "Update":
                        Person a = new Person();
                        string[] tempSt = splited[3].Split(new Char[] { ';' });
                        a.Age = Convert.ToInt32(tempSt[1]);
                        a.FName = tempSt[2];
                        a.LName = tempSt[3];
                        a.id = Convert.ToInt32(tempSt[4]);
                        ids.Update(a);
                        x.Clear();
                        x.read(path);
                        msg = "";
                        foreach (Person pp in x)
                        {
                            msg += pp.SaveToSCV();
                            msg += " ";
                        }
                        send();
                        break;

                    case "Delete":
                        x.delete(path, Convert.ToInt32(splited[3]));
                        x.Clear();
                        x.read(path);
                        msg = "";
                        foreach (Person pp in x)
                        {
                            msg += pp.SaveToSCV();
                            msg += " ";
                        }
                        send();
                        break;
                    default:
                        throw new ArgumentException();
                }
            }
            public void connect()
            {
                while (ThisSocket.Connected)
                {
                    if (networkStream.DataAvailable)
                    {
                        int i = ThisSocket.Available;
                        byte[] bytes = new byte[i];
                        //ThisSocket.Receive(bytes);
                        networkStream.Read(bytes, 0, i);
                        msg = Encoding.UTF8.GetString(bytes);
                        // Console.WriteLine(msg);
                        networkStream.Flush();
                        action(msg);
                    }
                }
            }
        }
        public void Stop()
        {
            foreach (Client p in lst)
            {               
                p.networkStream.Flush();
                p.ThisSocket.Close();
            }
            lst.Clear();
            state = false;
            serverLi.Stop();
        }
        public void Start()
        {
            serverLi = new TcpListener(port);
            serverLi.Start();
            Console.Write("Waiting for a connection... ");
            Client cl = null;
            state = true;
            while (state)
            {
                    cl = new Client(serverLi.AcceptSocket(), this);
                    lst.Add(cl);
                    Thread.Sleep(3000);
            }
        }
    }
}
